home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-17 | 20.6 KB | 667 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: FWMARead.cpp
- // Release Version: $ ODF 2 $
- //
- // Copyright: (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
- //
- // MacApp view resources reader
- //
- //========================================================================================
-
- #ifndef FWMAREAD_H
- #include "FWMARead.h"
- #endif
-
- #ifndef FWMAOBJS_H
- #include "FWMAObjs.h"
- #endif
-
- #ifndef FWSVIEW_H
- #include "FWSView.h"
- #endif
-
- #ifndef FWFRAME_H
- #include "FWFrame.h"
- #endif
-
- #ifndef FWFILEOP_H
- #include "FWFileOp.h"
- #endif
-
- #ifndef FWRESOUR_H
- #include "FWResour.h"
- #endif
-
- #ifndef SLFILESY_H
- #include "SLFileSy.h"
- #endif
-
- #ifndef FWMEMHLP_H
- #include "FWMemHlp.h"
- #endif
-
- #ifndef FWMEMMGR_H
- #include "FWMemMgr.h"
- #endif
-
- #include <stdio.h>
-
- //========================================================================================
- // Some MacApp Types & Constants
- //========================================================================================
-
- // template version for MacApp 3.0 views
- const short kMAThreeOhTemplateVersion = 0x0300;
-
- // UStream.h constants
- enum { kNoStandardObject, kStandardObject };
-
- enum { kNullObject, kLocalObjectNumber, kClassIDAndClassname, kSignatureAndClassname };
-
- enum { kDontForceReplacement, kForceReplacement };
-
- typedef long LocalObjectNumber;
-
- #pragma options align=mac68k
-
- typedef struct MATextStyle {
- Style tsFace; // character Style
- char filler; // tsFace is unpacked byte
- short tsSize; // size in points
- RGBColor tsColor; // absolute (RGB) color
- Str255 tsFont; // font (family) number
- } *MATextStylePtr, **MATextStyleHandle;
-
- #pragma options align=reset
-
- //========================================================================================
- // FW_CMacAppReader Static Members
- //========================================================================================
-
- short FW_CMacAppReader::gClassCount = 0;
- MAClassTableH FW_CMacAppReader::gTableH = 0;
-
- ResType FW_CMacAppReader::gDefaultButtonID = 0;
- ResType FW_CMacAppReader::gCancelButtonID = 0;
- FW_CMAScrollBarScroller* FW_CMacAppReader::gScroller = 0;
- FW_CRadioCluster* FW_CMacAppReader::gCluster = 0;
- FW_CPoint FW_CMacAppReader::gOffset = FW_kZeroPoint;
- FW_CMAClassCollection* FW_CMacAppReader::gClassCollection = 0;
- FW_PFileSpecification* FW_CMacAppReader::gCurResFileSpec = 0;
- FW_Boolean FW_CMacAppReader::gUseDebugWarnings = true;
-
- //========================================================================================
- // runtime information
- //========================================================================================
-
- FW_DEFINE_AUTO(FW_CMAClassCollection)
- FW_DEFINE_AUTO(FW_CMAClassDesc)
- FW_DEFINE_AUTO_TEMPLATE(FW_TOrderedCollectionIterator, FW_CMAClassDesc)
-
- //========================================================================================
- // class FW_CMacAppReader
- //========================================================================================
-
- #ifdef FW_BUILD_MAC
- #pragma segment fwmacapp
- #endif
-
- // ---------------------------------------------------------------------------
- // FW_CMacAppReader::CreateSubViewsFromMacAppResource
- // ---------------------------------------------------------------------------
-
- FW_PlatformError FW_CMacAppReader::CreateSubViewsFromMacAppResource(Environment* ev,
- FW_ResourceID resourceID,
- FW_CSuperView* superview,
- FW_MReceiver* receiver,
- EResourceFileKind resFileKind,
- FW_Boolean useDebugWarnings)
- {
- FW_PlatformError error = FW_xNoError;
-
- // Reset globales
- gScroller = 0;
- gCluster = 0;
- gOffset = FW_kZeroPoint;
- gDefaultButtonID = 0;
- gCancelButtonID = 0;
- gUseDebugWarnings = useDebugWarnings;
-
- // Pick the right resource file
- FW_PResourceFile* resFile = GetResFile(ev, resFileKind);
-
- // Try to find the MacApp view resource
- FW_TRY
- {
- // Create stream from resource.
- // This will fail is there is no View resource in this file.
- FW_PResource maResource(ev, *resFile, resourceID, FW_kMAType);
- FW_PResourceSink sink(ev, maResource);
- FW_CReadableStream maStream(sink);
-
- // MacApp version is first data in the stream
- short macappVersion;
- maStream >> macappVersion;
-
- if(macappVersion != kMAThreeOhTemplateVersion)
- {
- error = FW_xWrongViewResourceVersion;
- }
- else
- {
- // Read objects and create ODF views
- ReadStreamObject(ev, maStream, superview, receiver, kView);
-
- // Propagate the PostCreate method to finish creating the views
- PostCreateViewFromStream(ev, superview);
- }
- }
- FW_CATCH_BEGIN
- FW_CATCH_REFERENCE(FW_XException, except)
- {
- error = except.GetPlatformError();
- }
- FW_CATCH_EVERYTHING()
- {
- error = FW_xUnknownError;
- }
- FW_CATCH_END
-
- delete resFile;
-
- return error;
- }
-
- // ---------------------------------------------------------------------------
- // FW_CMacAppReader::GetResFile
- // ---------------------------------------------------------------------------
- // GetResFile returns 0 only when asking for a new resource file and cancelling
- // the file dialog. Otherwise it returns a valid external resource file or
- // the shared library itself.
-
- FW_PResourceFile* FW_CMacAppReader::GetResFile(Environment* ev,
- EResourceFileKind resFileKind)
- {
- FW_PResourceFile* resFile = 0;
- OSType maFileTypes[] = {'rsrc', 'RSRC', 'aLib', 'APPL'};
-
- if (resFileKind == kPartOnly || resFileKind == kPartOrAskUser)
- {
- resFile = FW_NEW(FW_PSharedLibraryResourceFile, (ev));
- }
- if (resFileKind == kCurrentResFile)
- {
- if (gCurResFileSpec == 0)
- {
- // Try to open the resource file ::sources:<part_name>.rsrc that was used
- // to build the project.
-
- FW_PSharedLibraryResourceFile shLibFile(ev);
- FW_PFileSpecification shLibFileSpec(ev, shLibFile->GetFileSpecification(ev));
- FW_PDirectorySpecification libDir(ev, shLibFileSpec->GetParentDirectory(ev));
- FW_CString libName;
- shLibFileSpec->GetName(ev, libName);
- FW_CString fileName(":Sources:");
- fileName += libName;
- fileName += ".rsrc";
-
- gCurResFileSpec = FW_NEW(FW_PFileSpecification, (ev, libDir, fileName));
- if (FW_FileSystem_IsValidFile(ev, *gCurResFileSpec) == false)
- {
- // Else put up the file dialog
- delete gCurResFileSpec;
- gCurResFileSpec = 0;
- FW_OFileSpecification* oSpec = FW_CChooseFile::ChooseFileToOpen(
- FW_COpenFileParameters(4, maFileTypes));
- if (oSpec != 0)
- gCurResFileSpec = FW_NEW(FW_PFileSpecification, (ev, oSpec));
- }
- }
-
- if (gCurResFileSpec != 0)
- resFile = FW_NEW(FW_PResourceFile, (ev, *gCurResFileSpec));
- else
- resFile = FW_NEW(FW_PSharedLibraryResourceFile, (ev));
- }
- else if (resFileKind == kNewResFile)
- {
- // Ask the user to pick a new file
- FW_OFileSpecification* oSpec = FW_CChooseFile::ChooseFileToOpen(
- FW_COpenFileParameters(4, maFileTypes));
- if (oSpec != 0)
- {
- delete gCurResFileSpec;
- gCurResFileSpec = FW_NEW(FW_PFileSpecification, (ev, oSpec));
- }
- if (gCurResFileSpec != 0)
- resFile = FW_NEW(FW_PResourceFile, (ev, *gCurResFileSpec));
- }
-
- return resFile;
- }
-
- // ---------------------------------------------------------------------------
- // FW_CMacAppReader::GetResFileName
- // ---------------------------------------------------------------------------
-
- void FW_CMacAppReader::GetResFileName(Environment* ev, FW_CString& name)
- {
- if (gCurResFileSpec != 0)
- (*gCurResFileSpec)->GetName(ev, name);
- else
- {
- FW_PSharedLibraryResourceFile shLibFile(ev);
- FW_PFileSpecification shLibFileSpec(ev, shLibFile->GetFileSpecification(ev));
- shLibFileSpec->GetName(ev, name);
- }
- }
-
- // ---------------------------------------------------------------------------
- // FW_CMacAppReader::ReadStreamObject
- // ---------------------------------------------------------------------------
-
- void FW_CMacAppReader::ReadStreamObject(Environment* ev,
- FW_CReadableStream& stream,
- FW_CSuperView* superview,
- FW_MReceiver* receiver,
- ENextObjectType type)
- {
- short delimiter;
- stream >> delimiter;
-
- if (delimiter == kLocalObjectNumber)
- {
- LocalObjectNumber itsObjectNumber;
- stream >> itsObjectNumber; // ODF ignores this object
- }
- else if (delimiter != kNullObject)
- {
- FW_CMAObject* currentObject = 0;
- if (delimiter == kClassIDAndClassname)
- {
- // Create an uninitialized object.
- currentObject = ReadObject(ev, stream);
- }
- else if (delimiter == kSignatureAndClassname)
- {
- // Create an uninitialized object by signature.
- currentObject = ReadStdObject(ev, stream, type);
- }
-
- else
- {
- MACAPP_WARNING("FW_CMacAppReader::ReadStreamObject: Unknown delimiter in resource stream");
- FW_Failure(FW_xReadableStream);
- }
-
- if (currentObject)
- {
- currentObject->ReadFrom(ev, stream, superview, receiver);
- }
- }
- }
-
- // ---------------------------------------------------------------------------
- // FW_CMacAppReader::ReadStdObject
- // ---------------------------------------------------------------------------
-
- FW_CMAObject* FW_CMacAppReader::ReadStdObject(Environment* ev,
- FW_CReadableStream& stream, ENextObjectType type)
- {
- FW_CMAObject* currentObject = 0;
- ResType classID;
-
- stream >> classID; // Read the object's signature.
-
- long sizePosition = ((FW_ORandomAccessSink *)stream.GetSink())->GetPosition(ev);
- long objectSize, endOfObject;
- stream >> objectSize;
- endOfObject = sizePosition + objectSize;
-
- FW_CString className = ReadStr255(stream);// Read its name.
-
- // Unlike MacApp we always start to find the class by name first then
- // we try by class signature (this allows to register all our supported
- // classes by signature only. The user can still register classes by name)
- if (className.IsEmpty() == false)
- currentObject = NewByClassName(className, classID);
- if (currentObject == 0)
- currentObject = NewBySignature(classID);
-
- if (currentObject == 0)
- {
- if (type == kView && classID != kStdScrollerScrollBar)
- {
- // View class wasn't registered. We replace it with a nice pink one!
- // It will display the class name or its signature
- if (className.IsEmpty())
- className.ReplaceAll((char*)&classID, 4);
-
- currentObject = FW_CMAUnknownView::Create(classID, className);
-
- // Keep the endOfObject position around to skip the data after
- // reading the TView fields
- currentObject->fEndOfObject = endOfObject;
- }
- else
- {
- // Otherwise we skip over non-view object data here.
- // WARNING: this may fail when using custom classes! "objectSize" is not
- // reliable in that case (known MacApp problem)
- ((FW_ORandomAccessSink *)stream.GetSink())->SetPosition(ev, endOfObject);
- }
- }
-
- return currentObject;
- }
-
- // ---------------------------------------------------------------------------
- // FW_CMacAppReader::ReadObject
- // ---------------------------------------------------------------------------
-
- FW_CMAObject* FW_CMacAppReader::ReadObject(Environment* ev, FW_CReadableStream& stream)
- {
- long streamID; // Class ID in stream.
- // long currentID; // Class ID in program.
-
- stream >> streamID; // Read the object's class ID.
-
- long sizePosition = ((FW_ORandomAccessSink *)stream.GetSink())->GetPosition(ev);
- long objectSize;
- stream >> objectSize;
-
- /**
- FW_CString className = ReadStr255(stream);// Read its name.
-
- if (className.IsEmpty()) // No class name. Must have seen the class before,
- { // so convert the streamID to the currentID.
- currentID = this->LookupClassID(streamID);
- }
- else
- { // Get ID from name ...
- currentID = ClassDesc::GetClassDescFromClassName(className)->GetClassID();
- this->RegisterClassID(streamID, currentID);// ... and register the IDs.
- }
-
- data = NULL;
-
- if (currentID == kNilClass) // Don't know about the class.
- {
- // If the streamID is kNilClass then the object was realy
- // NULL, which is a known object, otherwise the class
- // isn't available.
- known = streamID == kNilClass;
-
- // Skip over the object's data.
- this->SetPosition(sizePosition + objectSize);// Skip over its data.
- }
- else
- { // Create the object.
- data = (TObject*) ClassDesc::NewByClassID((ClassID) currentID);
- known = TRUE;
- }
- **/
- ((FW_ORandomAccessSink *)stream.GetSink())->SetPosition(ev, sizePosition + objectSize);
- return 0;
- }
-
- // ---------------------------------------------------------------------------
- // FW_CMacAppReader::NewBySignature
- // ---------------------------------------------------------------------------
-
- FW_CMAObject* FW_CMacAppReader::NewBySignature(ResType classID)
- {
- FW_CMAObject *theObject = 0;
- short index = FetchClassIndex(classID);
-
- if (index != 0)
- {
- theObject = (*(*gTableH)[index - 1].creatorFunc)(classID);
- }
- return theObject;
- }
-
- // ---------------------------------------------------------------------------
- // FW_CMacAppReader::NewByClassName
- // ---------------------------------------------------------------------------
-
- FW_CMAObject* FW_CMacAppReader::NewByClassName(FW_CString& className, ResType classID)
- {
- FW_CMAObject *theObject = 0;
-
- if (gClassCollection)
- {
- FW_TOrderedCollectionIterator<FW_CMAClassDesc> ite(gClassCollection);
- for (FW_CMAClassDesc* classDesc = ite.First(); ite.IsNotComplete();
- classDesc = ite.Next())
- {
- if (classDesc->fClassName == className)
- {
- theObject = classDesc->fClassCreator(classID);
- break;
- }
- }
- }
- return theObject;
- }
-
- // ---------------------------------------------------------------------------
- // FW_CMacAppReader::FetchClassIndex
- // ---------------------------------------------------------------------------
-
- short FW_CMacAppReader::FetchClassIndex(ResType classID)
- {
- short classIndex = 0;
- MAClassTable *tableP = *gTableH;
-
- for (short i = 0; i < gClassCount; i++)
- {
- if (tableP[i].classID == classID)
- {
- classIndex = i + 1;
- break;
- }
- }
- return classIndex;
- }
- // ---------------------------------------------------------------------------
- // FW_CMacAppReader::ReadStr255
- // ---------------------------------------------------------------------------
-
- FW_CString FW_CMacAppReader::ReadStr255(FW_CReadableStream& stream)
- {
- char byteCount;
-
- stream >> byteCount;
-
- FW_CAcquireTemporarySystemHandle handle(byteCount);
- char* buffer = (char*) handle.GetPointer();
- stream.Read(buffer, byteCount);
-
- return FW_CString(buffer, byteCount);
- }
-
- // ---------------------------------------------------------------------------
- // FW_CMacAppReader::GetTextStyle
- // ---------------------------------------------------------------------------
-
- void FW_CMacAppReader::GetTextStyle(short textStyleID,
- FW_CFont& font,
- FW_CColor& color)
- {
- MATextStyleHandle textStyleHdl = (MATextStyleHandle) GetResource('TxSt', textStyleID);
-
- if (textStyleHdl == 0)
- {
- if (textStyleID != -1)
- {
- MACAPP_WARNING("MacAppReader Warning: Missing MacApp TxSt resource");
- }
- font = FW_kNormalFont;
- color = FW_kRGBBlack;
- }
- else
- {
- FW_CString fontName;
- fontName.ReplaceAll((*textStyleHdl)->tsFont);
-
- // MacApp text styles use the empty string for the system font and "A"
- // for the application
- if (fontName.IsEmpty())
- fontName = FW_GetSystemFontName();
- else if (fontName == "A")
- fontName = FW_GetDefaultFontName();
-
- // ODF style matches Mac Style enum in Types.h
- FW_FontStyle style = (FW_FontStyle)(*textStyleHdl)->tsFace;
-
- int size = (*textStyleHdl)->tsSize;
- if (size == 0)
- size = 12;
-
- font = FW_CFont(fontName, style, FW_IntToFixed(size));
-
- color = (*textStyleHdl)->tsColor;
- }
- }
-
- // ---------------------------------------------------------------------------
- // FW_CMacAppReader::RegisterAllMacAppClasses
- // ---------------------------------------------------------------------------
- // Register all MacApp classes supported by ODF
-
- void FW_CMacAppReader::RegisterAllMacAppClasses()
- {
- FW_CMacAppReader::RegisterSignature(kStdButton, FW_CMAButton::Create);
- FW_CMacAppReader::RegisterSignature(kStdCheckBox, FW_CMAButton::Create);
- FW_CMacAppReader::RegisterSignature(kStdCluster, FW_CMACluster::Create);
- FW_CMacAppReader::RegisterSignature(kStdControl, FW_CMAControl::Create);
- FW_CMacAppReader::RegisterSignature(kStdDialogView, FW_CMADialog::Create);
- FW_CMacAppReader::RegisterSignature(kStdDialogBehavior, FW_CMADialogBehavior::Create);
- FW_CMacAppReader::RegisterSignature(kStdEditText, FW_CMAEditText::Create);
- FW_CMacAppReader::RegisterSignature(kStdTEView, FW_CMATEView::Create);
- FW_CMacAppReader::RegisterSignature(kStdPicture, FW_CMAPictSView::Create);
- FW_CMacAppReader::RegisterSignature(kStdPopup, FW_CMAPopupMenu::Create);
- FW_CMacAppReader::RegisterSignature(kStdRadio, FW_CMAButton::Create);
- FW_CMacAppReader::RegisterSignature(kStdScroller, FW_CMAScrollBarScroller::Create);
- FW_CMacAppReader::RegisterSignature(kStdStaticText, FW_CMAStaticText::Create);
- FW_CMacAppReader::RegisterSignature(kStdTextGridView, FW_CMATextGridView::Create);
- FW_CMacAppReader::RegisterSignature(kStdTextListView, FW_CMATextGridView::Create);
- FW_CMacAppReader::RegisterSignature(kStdView, FW_CMAView::Create);
- FW_CMacAppReader::RegisterSignature(kStdWindow, FW_CMAWindow::Create);
-
- #if 0
- MA_REGISTER_SIGNATURE(TIcon, kStdIcon);
- MA_REGISTER_SIGNATURE(TSmallIcon, kStdSmallIcon);
- MA_REGISTER_SIGNATURE(TNumberText, kStdNumberText);
- MA_REGISTER_SIGNATURE(TPattern, kStdPattern);
- MA_REGISTER_SIGNATURE(TTargetBorderView, kStdTargetBorderView);
- MA_REGISTER_SIGNATURE(TDialogTEView, kStdDialogTEView);
- #endif
- }
-
- // ---------------------------------------------------------------------------
- // FW_CMacAppReader::RegisterSignature
- // ---------------------------------------------------------------------------
-
- void FW_CMacAppReader::RegisterSignature(ResType classID, MAClassCreatorFunc creatorFunc)
- {
- short classIndex = 1; // One-based index into class table
-
- if (gClassCount == 0)
- {
- // Create new class table (ODNewHandle throws kODErrOutOfMemory if it fails)
- gTableH = (MAClassTableH) FW_CMemoryManager::AllocateSystemHandle(sizeof(MAClassTable));
- gClassCount = 1;
-
- }
- else
- {
- // See if class is already in table
- classIndex = FetchClassIndex(classID);
-
- if (classIndex == 0)
- {
- FW_CMemoryManager::ResizeSystemHandle((FW_PlatformHandle) gTableH,
- (gClassCount+1) * sizeof(MAClassTable));
- gClassCount++;
- classIndex = gClassCount;
- }
- }
- // Store ID and CreatorFunc
- (*gTableH)[classIndex - 1].classID = classID;
- (*gTableH)[classIndex - 1].creatorFunc = creatorFunc;
- }
-
- // ---------------------------------------------------------------------------
- // FW_CMacAppReader::RegisterClassName
- // ---------------------------------------------------------------------------
-
- void FW_CMacAppReader::RegisterClassName(FW_CString& className, MAClassCreatorFunc creatorFunc)
- {
- if (gClassCollection == 0)
- gClassCollection = FW_NEW(FW_CMAClassCollection, ());
-
- FW_CMAClassDesc* newClassDesc = FW_NEW(FW_CMAClassDesc, (className, creatorFunc));
-
- FW_TOrderedCollectionIterator<FW_CMAClassDesc> ite(gClassCollection);
- for (FW_CMAClassDesc* classDesc = ite.First(); ite.IsNotComplete();
- classDesc = ite.Next())
- {
- if (classDesc->fClassName == newClassDesc->fClassName)
- {
- // Not allowed to register the same class with 2 creators
- FW_ASSERT(classDesc->fClassCreator == newClassDesc->fClassCreator);
- return;
- }
- }
-
- gClassCollection->AddLast(newClassDesc);
- }
-
- // ---------------------------------------------------------------------------
- // FW_CMacAppReader::ReloadViews
- // ---------------------------------------------------------------------------
-
- FW_PlatformError FW_CMacAppReader::ReloadViews(Environment* ev,
- FW_ResourceID resourceID,
- FW_CFrame* frame,
- FW_MReceiver* receiver,
- EResourceFileKind resFileKind,
- FW_Boolean useDebugWarnings)
- {
- // Delete the whole view hierarchy under the frame
- frame->DeleteAndResetViews(ev);
-
- // Reload the views from the same resource file
- FW_PlatformError error = CreateSubViewsFromMacAppResource(ev, resourceID, frame,
- receiver, resFileKind, useDebugWarnings);
-
- frame->Invalidate(ev);
-
- return error;
- }
-
- // ---------------------------------------------------------------------------
- // FW_CMacAppReader::PostCreateViewFromStream
- // ---------------------------------------------------------------------------
- // This method is the same as FW_CSuperView::PrivPostCreateViewFromStream which
- // cannot be used in ODF 1 because it's private.
-
- void FW_CMacAppReader::PostCreateViewFromStream(Environment* ev, FW_CSuperView* view)
- {
- // Handle this view first
- view->PostCreateViewFromStream(ev);
-
- // Propagate to its subviews if any
- FW_CViewIterator ite(view);
- for (FW_CView* subview = ite.First(); ite.IsNotComplete(); subview = ite.Next())
- {
- if (subview->HasSubViews(ev))
- PostCreateViewFromStream(ev, (FW_CSuperView *)subview);
- else
- subview->PostCreateViewFromStream(ev);
- }
- }
-